package com.wuster.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wuster.constant.CategoryConstant;
import com.wuster.entity.Admin;
import com.wuster.entity.Category;
import com.wuster.entity.Product;
import com.wuster.exception.CategoryException;
import com.wuster.result.ResultCodeEnum;
import com.wuster.service.AdminService;
import com.wuster.service.CategoryService;
import com.wuster.mapper.CategoryMapper;
import com.wuster.service.ProductService;
import com.wuster.utils.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import static com.wuster.constant.CategoryConstant.CATEGORY_NAME_PATTERN;

/**
 * @author Admin
 * @description 针对表【category】的数据库操作Service实现
 * @createDate 2024-07-04 15:02:38
 */
@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService{

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private ProductService productService;
    @Autowired
    private AdminService adminService;

    @Override
    public void setCategoryStatus(Long categoryId, Integer state) {
        //判断state状态，如果为1将所属的商品state全设置为1
//        if (state == 1){
//            UpdateWrapper<Product> productUpdateWrapper = new UpdateWrapper<>();
//            productUpdateWrapper.eq("category_id",categoryId).set("state",1);
//            productService.update(productUpdateWrapper);
//        }
        if(!isValidCategoryId(categoryId)){
            throw new CategoryException(ResultCodeEnum.CATEGORY_ID_INVALID);
        }

        // 检查state是否为0或1
        if (state == null || (state != 0 && state != 1)) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_STATE_INVALID);
        }


        //需要根据token获取当前修改分类信息的用户id
        //再加上前端传来的信息，添加到数据库中
        //从ThreadLocal中取出管理员名
        Map<String,Object> map  = ThreadLocalUtil.get();
        String adminName = (String)map.get("adminName");
        //查出管理员的信息
        Admin admin = adminService.selectAdminByName(adminName);

        Integer adminId = Math.toIntExact(admin.getId());
        log.info("管理员id是{}",adminId);
        //需要根据token获取当前修改分类状态的用户id
        //Integer adminId = 3;

        Category category = new Category();
        category.setState(state);
        category.setUpdateAdmin(adminId);

        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getId,categoryId);
        categoryService.update(category,queryWrapper);
    }

    @Override
    public void addCategory(Category category) {
        //1分类名称限制字数且必须要有
        //2分类图片如果为null,前端若发现后端没提供，绑定一个默认图片
        //3序号字段未使用，可以默认设置为0
        //4state默认显示为0
        //5描述可以为空

        // 检查category.id是否为空或没有值
        if (category.getId() != null) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_ID_ISNULL_ADD);
        }
        //检查category里封装的各项信息：name,image,state
        checkCategoryInfo(category);
        // 检查category.name是否在数据库中已存在
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", category.getName());
        long count = categoryService.count(queryWrapper);
        if (count > 0) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_NAME_EXIST);
        }

        //需要根据token获取当前修改分类信息的用户id
        //再加上前端传来的信息，添加到数据库中
        //从ThreadLocal中取出管理员名
        Map<String,Object> map  = ThreadLocalUtil.get();
        String adminName = (String)map.get("adminName");
        //查出管理员的信息
        Admin admin = adminService.selectAdminByName(adminName);

        Integer adminId = Math.toIntExact(admin.getId());
        log.info("管理员id是{}",adminId);
        //需要根据token获取当前添加分类信息的用户id，以及更新id
        //再加上前端传来的信息，添加到数据库中
        //Integer adminId = 1;
        category.setCreateAdmin(adminId);
        category.setUpdateAdmin(adminId);
        category.setIsdeleted(0);
        categoryService.save(category);
    }

    @Override
    public void deleteCategory(Long categoryId) {

        if(!isValidCategoryId(categoryId)){
            throw new CategoryException(ResultCodeEnum.CATEGORY_ID_INVALID);
        }

        //删除id= categoryId的分类以及将所属的所有商品的categoryId置为未分类状态0
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Product::getCategoryId,categoryId);
        Product product = new Product();
        product.setCategoryId(Long.valueOf(CategoryConstant.NO_CATEGORY));
        productService.update(product,queryWrapper);

        categoryService.removeById(categoryId);
    }

    @Override
    public void setCategoryDetails(Category category) {
        //判断category中的state状态，如果为1将所属的商品state全设置为1
//        if (category.getState() == 1){
//            LambdaQueryWrapper<Product> productQueryWrapper = new LambdaQueryWrapper<>();
//            productQueryWrapper.eq(Product::getCategoryId,category.getId());
//            Product product = new Product();
//            product.setState(1);
//            productService.update(product,productQueryWrapper);
//        }
        log.info("传来的category是{}",category);
        if(!isValidCategoryId(category.getId())){
            throw new CategoryException(ResultCodeEnum.CATEGORY_ID_INVALID);
        }
        checkCategoryInfo(category);

        // 检查category.name是否在数据库中已存在
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", category.getName());
        queryWrapper.ne(category.getId() != null, "id", category.getId());
        long count = categoryService.count(queryWrapper);
        if (count > 0) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_NAME_EXIST);
        }

        //需要根据token获取当前修改分类信息的用户id
        //再加上前端传来的信息，添加到数据库中
        //从ThreadLocal中取出管理员名
        Map<String,Object> map  = ThreadLocalUtil.get();
        String adminName = (String)map.get("adminName");
        //查出管理员的信息
        Admin admin = adminService.selectAdminByName(adminName);

        Integer adminId = Math.toIntExact(admin.getId());
        log.info("管理员id是{}",adminId);
//        Integer adminId = 2;
        category.setUpdateAdmin(adminId);
        category.setIsdeleted(0);//默认添加的分类未被删除
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Category::getId,category.getId());

        categoryService.update(category,lambdaQueryWrapper);
    }

    @Override
    public Category getByCategoryId(Long categoryId) {

        if(!isValidCategoryId(categoryId)){
            throw new CategoryException(ResultCodeEnum.CATEGORY_ID_INVALID);
        }

        return categoryService.getById(categoryId);
    }
    public  boolean isImageUrlValid(String imageUrl) {
        try {
            //创建URL对象，将传入的图片URL字符串转换为URL对象
            URL url = new URL(imageUrl);
            // 打开HTTP连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 设置HTTP请求方法为HEAD，HEAD请求只会获取响应的头部信息，不会下载整个文件
            connection.setRequestMethod("HEAD");
            // 设置连接超时时间为5秒
            connection.setConnectTimeout(5000); // 5 seconds
            // 设置读取超时时间为5秒
            connection.setReadTimeout(5000);    // 5 seconds

            // 获取服务器响应代码
            int responseCode = connection.getResponseCode();

            // 如果响应代码是200（HTTP_OK），则图片URL有效，返回true；否则返回false
            return (responseCode == HttpURLConnection.HTTP_OK);
        } catch (IOException e) {
            // 如果发生IOException，认为图片URL无效，返回false
            return false;
        }
    }
    private Boolean isValidCategoryId(Long categoryId){
        // 检查categoryId是否有效
        if (categoryId == null || categoryId < 0) {
            return false;
        }

        // 检查categoryId是否存在
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getId,categoryId);
        long count = categoryService.count(queryWrapper);
        if (count == 0) {
            return false;
        }

        return true;
    }

    private void checkCategoryInfo(Category category){
        // 检查category.name是否存在且有值
        if (category.getName() == null || category.getName().isEmpty()) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_NAME_NOT_EMPTY);
        }

        // 检查category.name是否符合格式要求
        if (!CategoryConstant.CATEGORY_NAME_PATTERN.matcher(category.getName()).matches()) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_NAME_LIMIT);
        }

        // 检查category.image是否为空或不存在
        if (category.getImage() == null || category.getImage().isEmpty()) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_DEFAULT_IMAGE);
        }

        //检查图片url的有效性
        if(!isImageUrlValid(category.getImage())){
            throw new CategoryException(ResultCodeEnum.CATEGORY_IMAGE_INVALID);
        }


        // 检查category.state是否为0或1
        if (category.getState() == null || (category.getState() != 0 && category.getState() != 1)) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_STATE_INVALID);
        }

        // 检查 ordinalNumber 字段，如果为 null 或为空字符串，设置为默认值 "0"
        if (category.getOrdinalNumber() == null || category.getOrdinalNumber().isEmpty()) {
            category.setOrdinalNumber("0");
        }
        // 检查字符串是否仅包含数字且不以0开头
        if (!category.getOrdinalNumber().matches("^(0|[1-9]\\d*)$")) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_ORDINALNUMBER_INVALID);
        }
        //解析后的序号是否大于等于0
        int ordinalNumber = Integer.parseInt(category.getOrdinalNumber());
        log.info("ordinalNumber的值为{}",ordinalNumber);
        if (ordinalNumber < 0) {
            throw new CategoryException(ResultCodeEnum.CATEGORY_ORDINALNUMBER_INVALID);
        }
        // 检查 description 字段，如果为 null 或为空字符串，设置为默认值 ""
        if (category.getDescription() == null || category.getDescription().isEmpty()) {
            category.setDescription("");
        }
    }

}




